using System;
using Microsoft.VisualStudio.Coverage.Analysis;

namespace Crap4Net.CoverageParsers
{
    public class VSCoverageParser : BaseCoverageParser
    {

        protected override void ParseDataFromXml(string reportFileName)
        {
            String CoveragePath = System.IO.Path.GetDirectoryName(reportFileName);
            //CoverageInfoManager.ExePath = CoveragePath;
            //CoverageInfoManager.SymPath = CoveragePath;
            //CoverageInfo data = CoverageInfoManager.CreateInfoFromFile(reportFileName);
            CoverageInfo data = CoverageInfo.CreateFromFile(reportFileName, new string[] { CoveragePath }, new string[] { CoveragePath });
            CoverageDS ds = data.BuildDataSet(null);
            
            foreach (CoverageDSPriv.NamespaceTableRow namespaceRow in ds.NamespaceTable)
            {
                foreach (CoverageDSPriv.ClassRow classRow in namespaceRow.GetClassRows())
                {
                    foreach (CoverageDSPriv.MethodRow methodRow in classRow.GetMethodRows())
                    {
                        MethodSignature methodSignature = ParseMethodSignature(namespaceRow, classRow, methodRow);
                        int covargeValue = CalculateCoverageValue(methodRow);
                        var method = new CoverageDataEntry(methodSignature, covargeValue);
                        Data.Add(method);
                    }
                }
            }
        }

        private MethodSignature ParseMethodSignature(CoverageDSPriv.NamespaceTableRow namespaceRow, CoverageDSPriv.ClassRow classRow, CoverageDSPriv.MethodRow methodRow)
        {
            string dll = namespaceRow.ModuleName;
            string nameSpace = namespaceRow.NamespaceName;
            string typeName = classRow.ClassName;
            string methodName = CleanMethodName(methodRow.MethodName);
            string[] arguments = GetArguments(methodRow.MethodName);

            var methodSignature = new MethodSignature(dll, nameSpace, typeName, methodName, arguments);
            return methodSignature;
        }

        private string CleanMethodName(string methodName)
        {
            return methodName.Split(new char[] { '(' })[0];
        }

        private string[] GetArguments(string methodName)
        {
            int start = methodName.IndexOf('(');
            int end = methodName.IndexOf(')');

            string argString = methodName.Substring(start + 1, end - start - 1);
            if (string.IsNullOrEmpty(argString))
                return new string[] { };
            return argString.Split(new char[]{','});
        }

        private static int CalculateCoverageValue(CoverageDSPriv.MethodRow methodRow)
        {
            return (100 * (int)methodRow.BlocksCovered) / (int)(methodRow.BlocksCovered + methodRow.BlocksNotCovered);
        }
    }
}
